/*数据列表
 * 2019-06-09 修复无数据场景下，onResize td会被设置宽度的bug
 * @Author: kevin.huang 
 * @Date: 2018-07-21 13:32:01 
 * @Last Modified by: kevin.huang
 * @Last Modified time: 2019-04-05 14:13:29
 * Copyright (c): kevin.huang Released under MIT License
 */
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'tree', 'toolbar', "pagination"], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if (!global["$B"]) {
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $doc = $(document);
    var $body;
    function _getBody() {
        if (!$body) {
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;
    }
    var scrollWidth;
    /**
     *列默认配置
     ***/
    var defaultColOpts = {
        title: '',
        field: '', //字段
        width: 'auto',
        rowspan: 0, // 跨行
        colspan: 0, //跨列
        align: 'left', //对齐'left'、'right'、'center'
        sortable: true, //该列是否可以排序
        resizable: false, //可以调整宽度
        formatter: null //function (cellValue, rowData) {return cellValue }//单元格格式化函数
    };
    /**
     *datagrid全局配置
     ***/
    var defaultOpts = {
        title: '', //标题
        data: null, //列表数据 存在初始化数据时，优先用初始化数据
        url: '', //url
        fillParent: false, //是否占满父元素(垂直方向)
        loadImd: true, //是否立即加载
        toolbar: null, //工具栏，参考toolbar组件
        oprCol: true, //是否需要行操作列
        treeIconColor: undefined,//树形图标颜色
        oprColWidth: 'auto', //操作列宽度
        cols: [], //列配置，支持多表头
        idField: 'id', //id字段名称
        checkBox: true, //是否需要复选框
        isTree: false, //是否是树形列表
        pgposition: 'bottom', //分页工具栏位置 top,bottom,both ,none none表示不需要分页栏
        pageSize: 30, //页大小
        page: 1,
        startPage: 1,
        btnStyle: 'plain', //对应工具栏里的style
        showBtnText: true, //是否显示按钮
        pgBtnNum: 10, //页按钮数量
        iconCls: undefined, //图标   fa-table
        setParams: undefined, //设置参数
        splitColLine: 'k_datagrid_td_all_line', //分割线样式 k_datagrid_td_v_line、k_datagrid_td_h_line
        pageList: [15,20,25,30,35,40,55,70,80,90,100], //页大小选择
        sortField: undefined, //默认排序字段
        onDbClickRow: null, // function (data) { },//双击一行时触发 fn(rowData)
        onClickCell: null, // function (field, value) { },//单击一个单元格时触发fn(field, value)
        onCheck: null, //function () { },//复选事件
        onRowRender: null, // function (data) { },//行渲染事件
        onLoaded: null //function (data) { }//加载完成回调
    };
    var chkbox_w = 25;
    var trEvents = {
        dblclick: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            clearTimeout(_this.clickTimer);
            if (typeof _this.opts.onDbClickRow === "function") {
                setTimeout(function () {
                    _this.opts.onDbClickRow.call($t);
                }, 1);
            }
        }
    };
    var tdEvents = {
        mousemove: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            if (_this.opts.checkBox) {
                if ($t.position().left < 32) {
                    return true;
                }
            }
            var x = $t.offset().left;
            var endX = $t.width() + x;
            var left = e.pageX;
            $t.css("cursor", "default").removeData("splitX");
            if ((x - 3) <= left && left <= (x + 3)) {
                $t.css("cursor", "w-resize").data("splitX", left);
            } else if ((endX - 3) <= left && left <= (endX + 3)) {
                $t.css("cursor", "w-resize").data("splitX", left);
            }
        },
        mouseover: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            if($t.height() > 60){
                var $txt = $t.children(".k_datagrid_cell_text");
                if($txt.height() > 50){
                    if(!$txt.data("tipopts")){
                        var txt = $txt.text();
                        var len = $B.getCharWidth(txt, $txt.css("font-size"));
                        var mWidth = 300;
                        if(len < mWidth){
                            mWidth = len;
                        }
                        if (len > $txt.width()) {
                            _this.$tip = $txt.mousetip({
                                maxWidth:_getBody().width() / 3,
                                minWidth:mWidth,
                                activedColor:'#A2D8FF'
                            });
                            $txt.trigger("mouseenter",{left:e.pageX + 5, top:e.pageY + 5});
                        }
                    }
                }
            }
        },
        mouseout: function (e) {
        },
        dblclick: function (e) { },
        mousedown: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            var splitX = $t.data("splitX");
            if (splitX) {
                var keys = Object.keys(_this.moveXofs);
                var index;
                var scrollLeft = _this.scrollLeft;
                splitX = splitX + scrollLeft;
                for (var i = 0, len = keys.length; i < len; ++i) {
                    var posX = parseInt(keys[i]);
                    if ((splitX - 6) <= posX && posX <= (splitX + 6)) {
                        index = _this.moveXofs[posX];
                        break;
                    }
                }
                if (index) {
                    var targetTd = _this.hideTrTdArray.eq(index);
                    var preTd = targetTd.prev();
                    var targetTdMinWidth = targetTd.data("minWidth");
                    var preTdMinWidth = preTd.data("minWidth");
                    var minLeft = preTd.position().left + preTdMinWidth;
                    var dragParams = {
                        minLeft: minLeft,
                        preTdMinWidth: preTdMinWidth,
                        targetTdMinWidth: targetTdMinWidth,
                        targetTd: targetTd,
                        preTd: preTd
                    };
                    var targetLeft = targetTd.position().left;
                    if (!_this.splitMovingLine) {
                        _this.splitMovingLine = $("<div style='position:absolute;top:0;'  class='k_datagrid_moving_line'></div>").appendTo(_this.$scrollWrap);
                        _this.splitMovingLine.draggable({
                            axis: 'h',
                            cursor: 'w-resize',
                            onStartDrag: function (e) { //开始拖动
                                var state = e.state;
                                var _data = state._data;
                                var dragParams = state.movingTarget.data("dragParams");
                                _data.dragParams = dragParams;
                                _this.isDragResize = true;
                            },
                            onDrag: function (e) {
                                var _data = e.state._data;
                                var leftOffset = _data.leftOffset;
                                if (leftOffset < 0) {
                                    if (_data.left < _data.dragParams.minLeft) {
                                        _data.left = _data.dragParams.minLeft;
                                    }
                                }
                            },
                            onStopDrag: function (e) { //拖动结束
                                var state = e.state;
                                var _data = state._data;
                                var leftOffset = _data.leftOffset;
                                var dragParams = _data.dragParams;
                                var leftTd = dragParams.preTd;
                                var rightTd = dragParams.targetTd;
                                var leftWidth = leftTd.outerWidth();
                                var rightWidth = rightTd.outerWidth();
                                var l_new_width,r_new_width;
                                if (leftOffset < 0) {
                                    leftWidth = leftWidth + leftOffset;
                                    rightWidth = rightWidth - leftOffset;
                                    if (leftWidth < dragParams.preTdMinWidth) {
                                        leftWidth = dragParams.preTdMinWidth;
                                        rightWidth = rightWidth + leftWidth - preTdMinWidth;
                                    }
                                    leftTd.outerWidth(leftWidth);
                                    rightTd.outerWidth(rightWidth);
                                    l_new_width = leftWidth - 2;
                                    r_new_width = rightWidth - 2;
                                } else {
                                    leftWidth = leftWidth + leftOffset;
                                    rightWidth = rightWidth - leftOffset;
                                    if (rightWidth >= dragParams.targetTdMinWidth) {
                                        leftTd.outerWidth(leftWidth);
                                        rightTd.outerWidth(rightWidth);
                                        l_new_width = leftWidth - 2;
                                        r_new_width = rightWidth - 2;
                                    } else {
                                    }
                                }
                                _data.dragParams = undefined;
                                if(l_new_width){
                                    var isScroll = false;
                                    if (_this.$table.outerHeight() > _this.$bodyWrap.height()) {
                                        isScroll = true;
                                    }
                                    leftTd.children().outerWidth(l_new_width);
                                    rightTd.children().outerWidth(r_new_width);
                                    _this.updateColsWidthArray();
                                    _this._resizeTdSize(isScroll,$B.getScrollWidth());
                                    _this._setColPosition();
                                }
                                _this._hideToolBtnList();
                                _this.splitMovingLine.hide();
                                _this.isDragResize = false;
                            },
                            onMouseUp: function (args) {
                                _this.splitMovingLine.hide();
                            }
                        });
                    }
                    _this.splitMovingLine.css("left", targetLeft - scrollLeft).show().trigger("mousedown.draggable", {
                        pageX: e.pageX,
                        pageY: e.pageY,
                        which: e.which
                    }).data("dragParams", dragParams);
                }
            }
        },
        click: function (e) {
            var $t = $(this);
            var _this = $t.data("_this");
            if (!_this.isDragResize) {
                clearTimeout(_this.clickTimer);
                _this.clickTimer = setTimeout(function () {
                    if (typeof _this.opts.onClickCell === "function") {
                        _this.opts.onClickCell.call($t, $t.attr("filed"), $t.children("div").text());
                    }
                }, 200);
            }
        }
    };

    function _createToolbar() {
        var _this = this;
        if (!this.$toolwrap) {
            this.$toolwrap = [];
            this.$toolwrap.push($("<div class='k_datagrid_toolbar_wrap k_box_size'></div>").prependTo(this.jqObj));
        }
        for (var i = 0, l = this.$toolwrap.length; i < l; ++i) {
            this.$toolwrap[i].children().remove();
            if (this.opts.toolbar.length > 0) {
                var _opts = {
                    style: _this.opts.btnStyle, // plain / min  / normal /  big
                    showText: true,
                    methodsObject: _this.opts.methodsObject,
                    buttons: this.opts.toolbar
                };
                if ($B.config.toolbarOpts) {
                    $.extend(_opts, $B.config.toolbarOpts);
                }                
                new $B.Toolbar(this.$toolwrap[i].show(), _opts);
            } else {
                if(this.$toolwrap[i].hasClass("k_pagination_wrap")){
                    if(this.opts.pgposition === "none"  ){
                        this.$toolwrap[i].hide();
                    } 
                }else{
                    this.$toolwrap[i].hide();
                }                             
            }
        }        
    }

    function _sortClick(e) {
        var t = $(this);
        var $t = t.children();
        var opt = t.parent().data("opt");
        var sort;
        if ($t.hasClass('fa-down')) {
            $t.removeClass('fa-down').addClass("fa-up");
            sort = "desc";
        } else {
            $t.removeClass('fa-up').addClass("fa-down");
            sort = "asc";
        }
        var _this = e.data.ins;
        if (_this.opts.url !== '') {
            var sortField = "_col_sort_" + opt.field;
            var prs = $.extend({ pageSize: _this.pageSize }, _this.lastParams);
            prs[sortField] = sort;
            prs.page = 1;
            _load.call(e.data.ins, function () {
                _makeBody.call(e.data.ins);
            }, prs);
        }
        return false;
    }

    function _showSort() {
        $(this).children(".k_datagrid_cell_sort").width(12).slideDown(100);
    }

    function _hideSort(e) {
        $(this).children(".k_datagrid_cell_sort").slideUp(100);
    }
    /***复选事件
     *  fa-check-empty  fa-check fa-ok-squared
     * ***/
    function _checkEvent(e) {
        var $t = $(this);
        var $tr = $t.parent().parent();
        var $icon = $t.children("i");
        if ($t.hasClass("k_datagrid_chkbox_disabled")) {
            return false;
        }
        var isCheck = false;
        var setCls;
        if ($icon.hasClass("fa-check-empty")) {
            setCls = "fa-check";
            $icon.removeClass("fa-check-empty fa-ok-squared").addClass(setCls);
            isCheck = true;
        } else {
            setCls = "fa-check-empty";
            $icon.removeClass("fa-check fa-ok-squared").addClass(setCls);
        }
        var flag = $t.data("flag");
        var _this = $t.data("_this");
        var tbody = _this.$table.children("tbody");
        var trArray = tbody.children();
        var datas = [];
        if (flag) {
            trArray.each(function () {
                var $tr = $(this);
                var box = $tr.children().first().children("div");
                if (!box.hasClass("k_datagrid_chkbox_disabled")) {
                    $tr.data("isCheck", isCheck);
                    var $i = box.children("i");
                    if (isCheck) {
                        $i.removeClass("fa-check-empty fa-ok-squared").addClass(setCls);
                    } else {
                        $i.removeClass("fa-check fa-ok-squared").addClass(setCls);
                    }
                    datas.push($.extend(true, {}, $tr.data("data")));
                }
            });
        } else {
            $tr.data("isCheck", isCheck);
            datas.push($.extend(true, {}, $tr.data("data")));
            if (_this.opts.isTree) {
                var deep = $tr.data("treeDeep");
                if ($tr.data("isparent")) {
                    var nextTr = $tr.next();
                    while (nextTr.length > 0 && nextTr.data("treeDeep") > deep) {
                        datas.push($.extend(true, {}, $tr.data("data")));
                        nextTr.data("isCheck", isCheck);
                        nextTr.children().first().children().children().removeClass("fa-check-empty  fa-check fa-ok-squared").addClass(setCls);
                        nextTr = nextTr.next();
                    }
                } else { }
            }
            var len = trArray.length;
            var chkCount = 0;
            trArray.each(function () {
                if ($(this).data("isCheck")) {
                    chkCount++;
                }
            });
            var parentChkCls;
            if (chkCount === 0) {
                parentChkCls = "fa-check-empty";
            } else if (chkCount !== len) {
                parentChkCls = "fa-ok-squared";
            } else {
                parentChkCls = "fa-check";
            }
            var headerIcon = _this.$header.children().children().last().children().first().children("div").children("i");
            headerIcon.removeClass("fa-check-empty  fa-check fa-ok-squared").addClass(parentChkCls);
        }
        if (typeof _this.opts.onCheck === "function") {
            setTimeout(function () {
                _this.opts.onCheck(isCheck, datas);
            }, 10);
        }
    }
    function _getMoveXofs(startTd, _this) {
        var moveXofs = {};
        var scrollLeft = _this.scrollLeft;
        while (startTd.length > 0) {
            var ofs = parseInt(startTd.offset().left + scrollLeft);
            moveXofs[ofs] = startTd.data("i");
            startTd = startTd.next();
        }
        return moveXofs;
    }
    /***创建表头***/
    function _createHeader() {
        var _this = this;
        this.$headWrap.children().remove();
        this.titleTDs = {}, //最后一行td集合对象
            this.$header = $("<table></table>");
        var $tbody = $("<tbody></tbody>").appendTo(this.$header);
        var colHtml = [],
            rowspanCol = {},
            cols = _this.opts.cols,
            delTdArr = [],
            rowspanTd = [],
            sortableTd = [],
            colIndexFix = _this.opts.checkBox ? 1 : 0, //设置titleTDs开始下标
            lastRowIndex = cols.length - 1,
            isCheckBox = _this.opts.checkBox;
        var getColIndexFn = function (tr) {
            var colIndex = 0;
            tr.children().each(function () {
                var td = $(this),
                    colspan = td.attr("colspan");
                if (colspan) {
                    colIndex = colIndex + parseInt(colspan);
                } else {
                    colIndex = colIndex + 1;
                }
            });
            return colIndex;
        };
        /****
         * 先创建好tr td html放置于数组中，最后循环一次appendto
         * 处理colspan情况，colspan不需要处理，外部的json已经要求不能有多余的td
         * 处理rowspan情况
         * *****/
        var col, tr, lastColIndex, opt, colspan, rowspan, td, sortBtn,
            txtWrap, _tmpIdx, isUrl = _this.opts.url !== "",
            txtWrapHtml = "<div class='k_box_size k_datagrid_cell_text'></div>",
            sortHtml = "<div  class='k_datagrid_cell_sort k_box_size'><i class='k_datagrid_i_icon fa'></i></div>";
        for (var rowIdx = 0, l = cols.length; rowIdx < l; ++rowIdx) {
            col = cols[rowIdx];
            tr = $("<tr>");
            lastColIndex = 0;
            var isLastRow = rowIdx === lastRowIndex;
            if (isLastRow) {
                lastColIndex = col.length - 1; //计算记录共有多少列;
            }
            for (var j = 0, jl = col.length; j < jl; ++j) {
                opt = isLastRow ? $.extend({}, defaultColOpts, col[j]) : col[j];
                if (opt.width === "") {
                    opt.width = "auto";
                } else if (opt.width && !$.isNumeric(opt.width) && opt.width !== "auto") {
                    opt.width = parseFloat(opt.width.replace("px", ""));
                }
                colspan = opt.colspan ? 'colspan="' + opt.colspan + '"' : "";
                rowspan = opt.rowspan ? 'rowspan="' + opt.rowspan + '"' : "";
                td = $("<td " + rowspan + " " + colspan + " class='k_box_size'></td>");
                if (rowIdx === 0) {
                    td.css("border-top", "none");
                }
                if (j === 0) {
                    td.css("border-left", "none");
                }
                if (j === jl - 1) {
                    td.css("border-right", "none");
                }
                txtWrap = $(txtWrapHtml).appendTo(td);
                txtWrap.append("<div style='width:100%' class='k_datagrid_title_text k_box_size'>" + opt.title + "</div>");
                if (rowspan !== "") {
                    rowspanTd.push(td);
                }
                if (opt.sortable && isUrl) {
                    sortBtn = $(sortHtml).appendTo(td).on("click", {
                        ins: _this
                    }, _sortClick);
                    if (_this.opts.sortOrder === "desc") {
                        sortBtn.children("i").addClass("fa-down");
                    } else {
                        sortBtn.children("i").addClass("fa-up");
                    }
                    td.mouseenter(_showSort);
                    td.mouseleave(_hideSort);
                    sortableTd.push(td);
                }
                td.outerWidth(opt.width).on(tdEvents).data("_this", _this);
                /***
                 *循环已经添加到tr的td，计算当前的列索引 需要处理colspan的情况
                 ****/
                var colIndex = getColIndexFn(tr);
                //记录td归属的行、列
                td.data("index", {
                    "r": rowIdx,
                    "c": colIndex
                }).data("opt", opt);
                if (rowIdx === lastRowIndex) { //记录最后一行的td
                    var tmp = colIndexFix + j;
                    this.titleTDs[tmp] = td;
                }
                /*判断是否是被rowspan的单元格
                 *1)先将rowspan的列记录到rowspanCol,记录当前rowspan的范围
                 *2)如果该列存在rowspan，则取出然后判断当前的td是否在rowspan范围内，如果在则记录起来
                 * *****/
                var rowSpanMsg = rowspanCol[colIndex];
                if (rowSpanMsg && rowSpanMsg.span) {
                    if (rowIdx <= rowSpanMsg.rowIdx) {
                        td.hide();                      
                        delTdArr.push(td);
                        if (rowIdx === lastRowIndex) { //最后一行,将最后td的opt合并到rowspan的td上
                            var _opt1 = rowSpanMsg.td.data("opt");
                            var crOpt = td.data("opt");
                            var newOpt = $.extend({}, crOpt, _opt1);
                            delete newOpt.rowspan;
                            delete newOpt.colspan;
                            rowSpanMsg.td.data("opt", newOpt);
                            rowSpanMsg.td.outerWidth(newOpt.width);
                            _tmpIdx = colIndexFix + j;
                            this.titleTDs[_tmpIdx] = rowSpanMsg.td; //修正为colspan的td
                        }
                    }
                }
                //记录rowspan的列
                if (opt.rowspan) {
                    rowspanCol[colIndex] = {
                        span: true,
                        rowIdx: rowIdx + opt.rowspan - 1,
                        td: td
                    };
                }
                tr.append(td);
            }
            colHtml.push(tr);
        }
        //删除被rowspan的td
        for (var d = 0, ll = delTdArr.length; d < ll; ++d) {
            delTdArr[d].remove();
        }
        var checkboxIcon = "<i class='fa  fa-check-empty'></i>",
            isLast, chkTd, opTd;
        //往header添加创建的tr，并在此时加入checkbox operator列
        for (var k = 0, kl = colHtml.length; k < kl; ++k) {
            isLast = k === kl - 1;
            if (isCheckBox) {
                chkTd = $("<td style='border-left:none;' class='k_box_size' ><div style='width:" + (chkbox_w - 2) + "px' class='k_box_size k_datagrid_cell_chkbox'></div></td>");
                chkTd.data("opt", {
                    width: chkbox_w
                });
                chkTd.outerWidth(chkbox_w);
                colHtml[k].prepend(chkTd);
                lastColIndex = lastColIndex + 1;
            }
            if (_this.opts.oprCol && k === 0) {
                var oprWidth = 'auto';
                if (_this.opts.oprColWidth) {
                    oprWidth = _this.opts.oprColWidth;
                }
                opTd = $("<td rowspan='" + kl + "' class='k_box_size'  style='border-right:none;'><div  class='k_box_size k_datagrid_cell_text'><div class='k_datagrid_title_text k_box_size'>" + $B.config.oprColName + "</div></div></td>");
                colHtml[k].append(opTd.outerWidth(oprWidth));
                rowspanTd.push(opTd);
                _tmpIdx = lastColIndex + 1;
                this.titleTDs[_tmpIdx] = opTd; //operator
                opTd.data("operator", true).data("opt", {
                    width: oprWidth,
                    isOpr: true
                });
            }
            $tbody.append(colHtml[k]);
            if (isCheckBox && isLast) {
                chkTd = colHtml[k].children().first().children()
                    .append(checkboxIcon)
                    .click(_checkEvent).data("flag", true).data("_this", _this);
                this.titleTDs[0] = chkTd.parent(); //checkbox
                chkTd.data("opt", {
                    width: chkbox_w
                });
                this.titleCheckBox = chkTd.children("i");
            }
            if (_this.opts.onHeadRender) {
                _this.opts.onHeadRender.call(colHtml[k]);
            }
        }
        var wrapWidth = this.$headWrap.width();
        //第一行隐藏行
        var hideTr = $("<tr style='height:0;'/>");
        var autoTdArray = []; //隐藏行里面的auto列
        var keys = Object.keys(this.titleTDs);
        var _css, titleTd, widthValue, tmpTd, minTableWidth = 0,
            tmpWidth, minWidth, fs, userMinWidth, tdOpt;
        for (var m = 0, klength = keys.length; m < klength; ++m) {
            _css = {
                height: 0,
                "border-top": "none",
                "border-bottom": "none"
            };
            titleTd = this.titleTDs[keys[m]];
            if (m === 0) {
                _css["border-left"] = "none";
            }
            if (m === klength - 1) {
                _css["border-right"] = "none";
            }
            tdOpt = titleTd.data("opt");
            widthValue = tdOpt.width;
            tmpTd = $("<td class='k_datagrid_header_hide_td'/>").css(_css).appendTo(hideTr).outerWidth(widthValue).data("i", m).data("opt", tdOpt);
            if (widthValue === "auto") { //需要设置最小列宽
                fs = titleTd.find(".k_datagrid_title_text").css("font-size");
                minWidth = undefined;
                userMinWidth = tdOpt.minWidth;
                if (userMinWidth && userMinWidth !== "") {
                    if (!$.isNumeric(userMinWidth)) {
                        userMinWidth = parseInt(userMinWidth.replace("px", ""));
                    }
                    minWidth = userMinWidth;
                } else {
                    minWidth = $B.getCharWidth(tdOpt.title, fs) + 16;
                }
                minTableWidth = minTableWidth + minWidth;
                autoTdArray.push(tmpTd);
            } else {
                minWidth = $B.getCharWidth(tdOpt.title, fs) + 16;
                tmpWidth = $.isNumeric(widthValue) ? widthValue : parseFloat(widthValue.replace("px", ""));
                minTableWidth = minTableWidth + tmpWidth;
            }
            tmpTd.data("minWidth", minWidth);
            titleTd.data("minWidth", minWidth); //用于拖动改变大小
            titleTd.outerWidth("auto");
        }
        var i, len;
        if (wrapWidth < minTableWidth) {
            for (i = 0, len = autoTdArray.length; i < len; ++i) {
                autoTdArray[i].outerWidth(autoTdArray[i].data("minWidth"));
            }
        }
        this.autoTdArray = autoTdArray;
        this.minTableWidth = parseInt(minTableWidth + 1);
        hideTr.prependTo(this.$header);
        this.$header.appendTo(this.$headWrap);
        //自适应一次外层容器
        var tableWidth = this.$header.outerWidth();
        if (this.$header.width() < minTableWidth) {
            this.$header.width(minTableWidth);
        }
        var diffWidth = wrapWidth - tableWidth;
        if (diffWidth > 0) {
            this.$header.outerWidth("100%");
            for (i = 0, len = autoTdArray.length; i < len; ++i) {
                td = autoTdArray[i];
                tmpWidth = td.outerWidth();
                if (tmpWidth < td.data("minWidth")) {
                    td.outerWidth(td.data("minWidth"));
                }
            }
        }
        this.hideTrTdArray = hideTr.children();
        //记录td的实际宽度到data("outerWidth")
        var tmpCls = ".k_datagrid_cell_text";
        this.updateColsWidthArray();
        //列宽拖动功能记录坐标
        var startTd = hideTr.children().eq(colIndexFix);
        tmpCls = ".k_datagrid_cell_sort";
        setTimeout(function () {
            _this._setColPosition();
            //修正rowspan td的排序icon的高度bug
            var h, isIE = $B.isIE();
            for (i = 0, len = sortableTd.length; i < len; ++i) {
                td = sortableTd[i];
                var $sort = td.children(tmpCls);
                if (isIE) {
                    h = td.outerHeight() - 1;
                } else {
                    h = td.height();
                }
                $sort.height(h);
            }
        }, 300);
    }
    /***树节点事件***/
    function _treeClick(e) {
        var _this = e.data._this;
        var $span = $(this);
        var tr = $span.parent().parent().parent();
        var treeDeep = tr.data("treeDeep");
        var icon = $span.children("i");
        var isClosed;
        if (icon.hasClass("fa-folder-open")) {
            icon.removeClass("fa-folder-open").addClass("fa-folder");
            isClosed = true;
        } else {
            icon.removeClass("fa-folder").addClass("fa-folder-open");
            isClosed = false;
        }
        tr.data("closed", isClosed);
        var nextTr = tr.next();
        var data = tr.data("data");
        //远程加载
        if (!isClosed && $.isArray(data.children) && data.children.length === 0) {
            var pLeft = $span.parent().css("padding-left");
            var loadingTr = $("<tr><td style='padding-left:" + pLeft + "' class='k_box_size' colspan='" + tr.children().length + "'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + $B.config.loading + "</td></tr>");
            var opts = _this.opts;
            loadingTr.insertAfter(tr);
            var params = $.extend({
                pid: data.data[opts.idField]
            }, _this.lastParams);
            if (typeof opts.setParams === "function") {
                $.extend(params, _this.opts.setParams());
            }
            var ajaxOpts = {
                async: true,
                url: opts.url,
                data: params,
                ok: function (message, data) {
                    if (data.length > 0) {
                        data.children = data;
                    }
                    for (var i = 0, len = data.length; i < len; ++i) {
                        _createTr.call(_this, data, tr, parseInt(treeDeep) + 1, false);
                    }
                    if (opts.onLoaded) {
                        setTimeout(function () {
                            opts.onLoaded(data);
                        }, 10);
                    }
                },
                final: function (res) {
                    var isEmpty = false;
                    if (typeof res.data !== "undefined") {
                        if (res.data.length === 0) {
                            isEmpty = true;
                        }
                    } else if ($.isArray(res) && res.length === 0) {
                        isEmpty = true;
                    }
                    if (isEmpty) {
                        loadingTr.children().html("<i style='padding-right:6px;' class='fa fa-info _no_data'></i>" + $B.config.noData);
                        setTimeout(function () {
                            loadingTr.remove();
                            icon.removeClass("fa-folder-open").addClass("fa-folder");
                        }, 1600);
                    } else {
                        loadingTr.remove();
                    }
                }
            };
            _this.ajax(ajaxOpts);
        } else {
            var deep, parentTrArray = [],
                parentStatus = {};
            parentStatus[treeDeep] = isClosed;
            while (nextTr.length > 0) {
                deep = nextTr.data("treeDeep");
                if (deep <= treeDeep) {
                    break;
                }
                if (isClosed) { //关闭则所有都要关闭
                    nextTr.hide();
                } else { //显示，并不一定都是需要显示
                    if (deep === treeDeep + 1) {
                        nextTr.show();
                    }
                    if (nextTr.data("isparent")) { //处理下级元素
                        parentTrArray.push(nextTr);
                        parentStatus[deep] = nextTr.data("closed");
                    }
                }
                nextTr = nextTr.next();
            }
            //循环处理parent show
            var $p, pStatus;
            for (var i = 0, len = parentTrArray.length; i < len; ++i) {
                $p = parentTrArray[i];
                deep = $p.data("treeDeep");
                isClosed = $p.data("closed");
                pStatus = parentStatus[deep - 1];
                if (!isClosed && !pStatus) {
                    deep = deep + 1;
                    nextTr = $p.next();
                    while (nextTr.length > 0 && nextTr.data("treeDeep") === deep) {
                        nextTr.show();
                        nextTr = nextTr.next();
                    }
                }
            }
            _this._onResize();
        }
        var selection;
        if (window.getSelection) {
            selection = window.getSelection();
        } else if (document.selection) {
            selection = document.selection.createRange();
        }
        try {
            selection.removeAllRanges();
        } catch (ex) { }
        return false;
    }
    function getTxtFromData(data,field){
        if(field.indexOf(".") > 0){
            var fieldArray = field.split(".");
            var objVal = data;            
            for(var i = 0 ,len = fieldArray.length ;i < len ;++i){
                objVal = objVal[fieldArray[i]];
            }
            return objVal;
        }else{
            return data[field];
        }
    }
    /***创建行***/
    function _createTr(list, vBody, treeDeep, parentIsClose) {
        var _this = this;
        var isTree = this.opts.isTree;
        var titleKeys = Object.keys(this.titleTDs);
        var $tr, data, idx, _txt, $txt;
        var tempArray = [];
        var isTbody = vBody[0].nodeName === "TBODY";
        for (var j = 0, dl = list.length; j < dl; ++j) {
            $tr = $("<tr/>");
            data = list[j];
            idx = 0;
            $tr.data("data", data).data("opts", this.opts).data("treeDeep", treeDeep);
            if (_this.opts.splitColLine !== "k_datagrid_td_all_line") {
                $tr.addClass("k_datagrid_old_even_cls");
            }
            for (var p = 0, plen = titleKeys.length; p < plen; ++p) {
                var tdHeader = _this.titleTDs[p],
                    tdOpt = tdHeader.data("opt"),
                    _width = _this.colsWidthArray[p],
                    innerWidth = _width - 2;
                if (j === 0) {
                    tempArray.push(_width);
                }
                var filed = tdOpt.field ? tdOpt.field : "";
                var $td = $("<td filed='" + filed + "' class='k_box_size'></td>");
                $td.outerWidth(_width);
                if (p === 0) {
                    $td.css("border-left", "none");
                }
                if (p === plen - 1) {
                    $td.css("border-right", "none");
                }
                if (_this.opts.splitColLine) {
                    $td.addClass(_this.opts.splitColLine);
                }
                if (_this.opts.checkBox && p === 0) { //checkbox
                    $('<div class="k_box_size k_datagrid_cell_text k_datagrid_cell_chkbox"><i class="fa  fa-check-empty"></i></div>').appendTo($td);
                    $txt = $td.css("text-align", "center").data("isCheckBox", true).children("div")
                        .data("data", data)
                        .data("_this", _this)
                        .data("treeDeep", treeDeep);
                    if (isTree && data.children) {
                        $txt.data("isparent", true);
                        if (_this.opts.onlyChkChild) {
                            $txt.addClass("k_datagrid_cell_chkbox_disabled");
                        }
                    }
                    $txt.click(_checkEvent).dblclick(function () {
                        return false;
                    });
                } else {
                    var txt, txtAlign = 'center',
                        isOperator = tdHeader.data("operator");
                    if (isOperator) { //operator
                        txt = '';
                        $td.css("text-align", "center");
                    } else { //data
                        if (isTree) {
                            txt =  getTxtFromData(data.data,tdOpt.field);
                        } else {
                            txt = getTxtFromData(data,tdOpt.field);
                        }
                        if (tdOpt.align) {
                            txtAlign = tdOpt.align;
                        }
                        if (typeof txt === "undefined") {
                            txt = "";
                        }
                    }
                    $txt = $('<div style="text-align:' + txtAlign + ';word-break: break-all;" class="k_box_size k_datagrid_cell_text k_mutilline_ellipsis"></div>').appendTo($td);
                    if (tdOpt && !isOperator) {
                        _txt = undefined;
                        if (typeof tdOpt.formatter === "function") {
                            _txt = tdOpt.formatter.call($td,txt, data, tdOpt.field);
                        } else if (typeof window[tdOpt.formatter] === "function") {
                            _txt = window[tdOpt.formatter].call($td,txt, data, tdOpt.field);
                        }
                        if (typeof _txt !== "undefined") {
                            txt = _txt;
                        }
                    }
                    $txt.html(txt);
                    $txt.appendTo($td);
                    $td.data("txt", $txt.text());
                    if (isTree) { //如果是树形  k_datagrid_cell_text_nowrap
                        var isFirstTd = (_this.opts.checkBox && p === 1) || (!_this.opts.checkBox && p === 0);
                        if (isFirstTd) {
                            var _treeDeep = treeDeep,
                                _padding = 0;
                            while (_treeDeep > 0) {
                                _padding = _padding + 20;
                                _treeDeep--;
                            }
                            if (_padding === 0) {
                                _padding = 2;
                            }
                            $txt.css({
                                "text-align": "left",
                                "padding-left": _padding
                            });
                            var $i;
                            if (data.children) {
                                var icon_cls = 'fa-folder';
                                var isClosed = true;
                                if (data.children.length > 0 && !data.closed) {
                                    icon_cls = 'fa-folder-open';
                                    isClosed = false;
                                }
                                $tr.data("closed", isClosed);
                                $i = $("<span style='cursor:pointer;'><i style='padding:2px 6px 2px 2px;cursor:pointer;' class='fa " + icon_cls + "'></i></span>").prependTo($txt);
                                $i.on("click", {
                                    _this: _this
                                }, _treeClick).dblclick(function () {
                                    return false;
                                });
                                $i = $i.children();
                            } else {
                                $i = $("<i style='padding:2px 6px 2px 2px;' class='fa fa-doc'></i>").prependTo($txt);
                            }
                            if (_this.opts.treeIconColor) {
                                $i.css("color", _this.opts.treeIconColor);
                            }
                        }
                    }
                    if (isOperator) {
                        var _btns = data.toolbar; //兼容 tree数据
                        if (_btns) {
                            delete data.toolbar;
                            var lineBtnOpts = $.extend( {
                                context: $tr, //点击事件的上下文
                                params: data, //用于集成到tree datagrid时 行按钮的数据参数
                                align: 'center', //对齐方式，默认是left 、center、right
                                style: _this.opts.btnStyle, //'plain',// plain / min  / normal /  big
                                showText: _this.opts.showBtnText, // min 类型可以设置是否显示文字
                                methodsObject: _this.opts.methodsObject, //事件集合对象
                                fontSize: '16',
                                iconColor: $B.config.rowBtnColor,
                                buttons: _btns
                            },_this.opts.lineBtnOpts);
                            _this.rowToolbars.push(new $B.Toolbar($txt,lineBtnOpts ));
                            //修正字体图标渲染延后的bug
                            $td.data("isOpr", true);
                            $td.data("oprCount", _btns.length);
                        }
                    } else {
                        $td.on(tdEvents).data("opts", _this.opts).data("field", tdOpt.field).data("_this", _this);
                    }
                }
                $td.children(".k_datagrid_cell_text").outerWidth(innerWidth);
                $tr.append($td);
                idx = idx + 1;
            }
            if (isTbody) {
                vBody.append($tr);
            } else {
                $tr.insertAfter(vBody);
            }
            $tr.on(trEvents).data("_this", _this);
            if (_this.opts.onRowRender) {
                _this.opts.onRowRender.call($tr, data, j);
            }
            if (isTree) {
                if (parentIsClose) {
                    $tr.hide();
                }
                if (data.children) {
                    var _len = data.children.length;
                    $tr.data("isparent", true).data("childrens", _len).data("checked", 0);
                    if (_len > 0) {
                        if (typeof parentIsClose !== "undefined" && parentIsClose) {
                            data.closed = parentIsClose;
                        }
                        if (isTbody) {
                            _createTr.call(this, data.children, vBody, treeDeep + 1, data.closed);
                        } else {
                            _createTr.call(this, data.children, $tr, treeDeep + 1, data.closed);
                        }
                    }
                }
            }
        }
    }

    function _makeBody() {
        var _this = this,
            topPgPostion = "right",
            display,
            list,
            treeDeep = 0;
        if (this.opts.isTree) {
            list = this.opts.data;
        } else {
            list = this.opts.data.resultList;
        }
        for (var k = 0, klen = this.rowToolbars.length; k < klen; ++k) {
            this.rowToolbars[k].destroy();
        }
        _this.rowToolbars = [];
        if (!this.$toolwrap) {
            this.$toolwrap = [];
            display = _this.showToolbar ? 'block' : 'none';
            if (this.$title) {
                var tmp = $("<div style='display:" + display + "' class='k_datagrid_toolbar_wrap k_box_size clearfix'></div>").insertAfter(this.$title);
                this.$toolwrap.push(tmp);
            } else {
                this.$toolwrap.push($("<div  style='display:" + display + "'  class='k_datagrid_toolbar_wrap k_box_size clearfix'></div>").prependTo(this.jqObj));
            }
        }
        if (!this.opts.isTree) {
            for (var l = 0, ll = _this.pgList.length; l < ll; ++l) {
                _this.pgList[l].clear();
            }
            _this.pgList = [];
            var pgOpts = {
                height: 25,
                page: this.opts.data.currentPage,
                total: this.opts.data.totalSize, //总数量
                pageSize: this.opts.pageSize, //页大小
                buttons: this.opts.pgBtnNum ? this.opts.pgBtnNum : 10, //页按钮数量
                startpg: this.opts.startPage > this.opts.data.currentPage ? this.opts.data.currentPage : this.opts.startPage,
                position: topPgPostion,
                summary: true,
                onClick: function (p, ps, startpg) {
                    _this.opts.startPage = startpg;
                    _this.opts.page = p;
                    _this.opts.pageSize = ps;
                    _this.pageSize = ps;
                    var prs = $.extend(_this.lastParams, {
                        page: p,
                        pageSize: ps
                    });
                    _load.call(_this, function () {
                        _makeBody.call(_this);
                    }, prs);
                }
            };
            //创建分页工具栏  "currentPage":1,"totalSize":2
            if (this.opts.pgposition === "both" || this.opts.pgposition === "top") {
                var $pgTool = this.$toolwrap[0].children("k_datagrid_pagination_top_wrap");
                if ($pgTool.length === 0) {
                    $pgTool = $("<div class='k_datagrid_pagination_top_wrap' style='float:" + topPgPostion + "'></div>").appendTo(this.$toolwrap[0]);
                }
                _this.pgList.push(new $B.Pagination($pgTool, pgOpts));
            }
            if (this.opts.pgposition === "both" || this.opts.pgposition === "bottom") {
                if (this.$toolwrap.length === 1) {
                    var tmpCls = "";
                    if (_this.opts.fillParent) {
                        tmpCls = "k_datagrid_tool_bottom_border";
                    }
                    this.$toolwrap.push($("<div class='k_datagrid_toolbar_wrap k_box_size " + tmpCls + "'></div>").appendTo(this.jqObj));
                }
                pgOpts.position = "left";
                _this.pgList.push(new $B.Pagination(this.$toolwrap[1], pgOpts));
            }
        }
        /****
         * 循环列表---》循环标题行----》创建tr td
         * _autoTDS将auto列的td记录起来
         * ******/
        if (list.length > 0) {
            this.$table.children("tbody").remove();
            var vBody = $("<tbody/>");
            this.updateColsWidthArray();
            _createTr.call(this, list, vBody, treeDeep);
            vBody.children().first().children().each(function () {
                $(this).css("border-top", "none");
            });
            this.$table.append(vBody);
            _this._onResize();
        }
    }

    function _load(fn, params) {
        if (window["$curTip_"]) {
            window["$curTip_"].hide();
            window["$curTip_"] = undefined;
        }
        var _this = this;
        var opts = this.opts;
        if (opts.url === "") {
            return;
        }
        if (this.titleCheckBox) {
            this.titleCheckBox.removeClass("fa-check fa-ok-squared").addClass("fa-check-empty");
        }
        if (typeof opts.setParams === "function") {
            $.extend(params, this.opts.setParams());
        }
        var mainWrap = this.$bodyWrap.parent().parent();
        if (!this.$mask) {
            var loadingTip = $B.config.loading;
            var w = $B.getCharWidth(loadingTip) + 20;
            var loadingHtml = "<div style='width:" + w + "px;z-index:2147483647;' class='k_datagrid_loading'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + loadingTip + "</div>";
            this.$mask = $("<div class='k_datagrid_load_mask'><div style='display:block;' class='k_model_mask'></div>" + loadingHtml + "</div>").appendTo(mainWrap);
        }
        var Headerheight = 0;
        this.$scrollWrap.prevAll().each(function () {
            Headerheight = Headerheight + $(this).outerHeight();
        });
        Headerheight = Headerheight + this.$headWrap.outerHeight();
        var bodyHeight = this.$bodyWrap.height();
        var fixPadding = false;
        if (bodyHeight === 0) {
            this.$bodyWrap.css("padding-bottom", 40);
            fixPadding = true;
        }
        this.$mask.children(".k_datagrid_loading").css("margin-top", Headerheight + 10);
        this.$mask.show().fadeIn(100);
        _this.lastParams = params;
        //补充上排序字段
        if (this.opts.sortField) {
            var fieldKeys = Object.keys(this.opts.sortField),
                field,sortKey;
            for (var j = 0, jlen = fieldKeys.length; j < jlen; ++j) {
                field = fieldKeys[j];
                sortKey = "_col_sort_" + field;
                if (!params[field] && !params[sortKey]) {
                    params[sortKey] = this.opts.sortField[field];
                }
            }
        }
        var ajaxOpts = {
            async: true,
            url: opts.url,
            data: params,
            ok: function (message, data,res) {
                if(data.config){/****动态表头支持********/
                    var cfg ;
                    if($.isPlainObject(data.config)){
                        cfg = data.config;
                    }else{
                        cfg = eval('('+data.config+')');
                    }
                    _this.opts.toolbar = cfg.toolbar;
                    _this.opts.cols = cfg.cols;
                    _this.opts.oprCol = cfg.oprCol;
                    _this.opts.checkBox = cfg.checkBox;
                    console.log("成功返回》》》》");
                    _createToolbar.call(_this);
                    _createHeader.call(_this);
                }
                _this.opts.data = data;
                _this.opts.data.currentPage = params.page;
                _this.opts.data.totalSize = data.totalSize; //总数量
                _this.opts.pageSize = params.pageSize; //页大小
                _makeBody.call(_this);
                if (opts.onLoaded) {
                    setTimeout(function () {
                        opts.onLoaded(data);
                    }, 10);
                }
                if ($B.isIE()) {
                    _this._fixIE();
                }
            },
            final: function (res) {
                var isEmpty = false;
                if (typeof res.data !== "undefined") {
                    if ((_this.opts.isTree && res.data.length === 0) || !res.data.totalSize) {
                        isEmpty = true;
                    }
                } else if ((_this.opts.isTree && $.isArray(res) && res.length === 0) || !res.totalSize) {
                    isEmpty = true;
                }
                if (isEmpty) {
                    _this.$table.children("tbody").remove();
                    var w = _this.$bodyWrap.width() - 2;
                    var emptyTr = $("<tbody><tr><td style='text-align:center;width:" + w + "px' class='k_box_size' colspan='" + _this.$header.children().children().first().children().length + "'><i style='padding-right:6px;' class='fa fa-info  _no_data'></i>" + $B.config.noData + "</td></tr></tbody>");
                    _this.$table.append(emptyTr);
                }
                if (fixPadding) {
                    _this.$bodyWrap.css("padding-bottom", 0);
                }
                _this.$mask.fadeOut(200, function () {
                    _this.$mask.hide();
                });
            }
        };
        this.ajax(ajaxOpts);
    }
    /**
     * 构造函数
     * **/
    function Datagrid(target, opts) {
        $B.extend(this, Datagrid); //继承父类
        this.opts = $.extend({}, defaultOpts, opts);
        this.scrollLeft = 0;
        if (!$.isArray(this.opts.cols[0])) {
            this.opts.cols = [this.opts.cols];
        }
        if (!scrollWidth) {
            scrollWidth = $B.getScrollWidth();
        }
        this["tdTip"] = _getBody().children("#k_datagrid_td_tip");
        if (this["tdTip"].length === 0) {
            this["tdTip"] = $("<div id='k_datagrid_td_tip' style='width:auto;min-width:150px;display:none;top:-1000px;' class=' k_box_shadow'><p></p></div>").appendTo(_getBody());
        }
        this.showToolbar = (!$.isArray(this.opts.toolbar) || this.opts.toolbar.length === 0) ? false : true;
        if (!this.showToolbar) {
            this.showToolbar = this.opts.pgposition === "top" || this.opts.pgposition === "both";
        }
        this.page = this.opts.page;
        this.pageSize = this.opts.pageSize;
        target.addClass("k_datagrid_table_body");
        this.jqObj = $('<div style="overflow:hidden" class="k_datagrid_main_wrap k_box_size"><div class="k_datagrid_scroll_wrap k_box_size"><div class="k_datagrid_head_wrap k_box_size"></div><div class="k_datagrid_body_wrap k_box_size" style="width:auto">' + target[0].outerHTML + '</div></div></div>');
        this.$bodyWrap = this.jqObj.find(".k_datagrid_body_wrap");
        this.$scrollWrap = this.jqObj.find(".k_datagrid_scroll_wrap").css({"overflow-x":"auto","overflow-y":"visible"});
        this.$headWrap = this.jqObj.find(".k_datagrid_head_wrap");
        this.$table = this.$bodyWrap.find("table");
        this.jqObj.insertAfter(target);
        target.remove();
        this.pgList = [];
        this.rowToolbars = [];
        this.$bodyWrap.addClass("k_datagrid_body_border_fix");
        var _this = this;
        if ($.isArray(this.opts.toolbar) && this.opts.toolbar.length > 0) {
            _createToolbar.call(this);
        }
        if (this.opts.title && this.opts.title !== '') {
            this.$title = $("<div class='k_datagrid_head_title k_box_size'></div>").prependTo(this.jqObj);
            this.$title.append("<h6 style='overflow:hidden;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp:1' class=''>" + this.opts.title + "</h6>").appendTo(this.$title);
            if (this.opts.iconCls !== '') {
                this.$title.children().prepend('<i class="fa ' + this.opts.iconCls + '"></i>&nbsp');
            }
        }
        var isExist = false;
        if (this.opts.url !== "") {
            for (var i = 0, l = this.opts.pageList.length; i < l; ++i) {
                if (this.opts.pageList[i] === this.opts.pageSize) {
                    isExist = true;
                    break;
                }
            }
            if (!isExist) {
                this.opts.pageList.push(this.opts.pageSize);
            }
        }
        _createHeader.call(this);
        _this._fillParent();
        //优先本地数据
        if (this.opts.data !== null) {
            setTimeout(function () {
                _makeBody.call(_this);
            }, 0);
        } else if (this.opts.url !== '' && this.opts.loadImd) {
            var params = {
                page: 1,
                pageSize: this.opts.pageSize
            };
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, params);
        }
        if (!this.showToolbar && this.opts.title === "") {
            this.jqObj.css("border-top", "none");
        }
        var delayFixTimer;
        var nsId = $B.getUUID();
        $(window).on("resize."+nsId,function () {
            if(_this._onResize){
                if(_this.$tip){
                    _this.$tip = undefined;
                    if( window["$curTip_"]){
                        window["$curTip_"].hide();
                    }
                }
                clearTimeout(delayFixTimer);
                delayFixTimer = setTimeout(function () {
                    _this._onResize();
                }, 20);
            }else{
                $(this).off("."+nsId);
            }
        });
    }
    Datagrid.prototype = {
        _fixIE: function () {
            if (!this.hasFixIe) {
                this.hasFixIe = true;
                if (this.hideTrTdArray.length > 1) {
                    var targetTd = this.hideTrTdArray.eq(1);
                    var prevTd = this.hideTrTdArray.eq(0);
                    prevTd.outerWidth(prevTd.outerWidth() + 1);
                    targetTd.outerWidth(targetTd.outerWidth() - 1);
                    this._onResize();
                }
            }
        },
        _hideToolBtnList: function () {
            if (this.opts.oprCol) {
                _getBody().children("#k_toolbar_drop_wrap").hide();
            }
        },
        _setBodyWrapHeight:function(fixBum){
            var parentHeight = this.jqObj.parent().height();
            var siblingsHeight = this.$headWrap.outerHeight();          
            this.$scrollWrap.siblings().each(function () {
                var $t = $(this);
                if (!$t.hasClass("k_datagrid_load_mask")) {
                    siblingsHeight = siblingsHeight + $t.outerHeight();
                }
            });
            var bodyFixedHeight = parentHeight - siblingsHeight;
            if(fixBum){
                bodyFixedHeight = bodyFixedHeight - fixBum;
            }
            var el = this.$bodyWrap.parent()[0];
            var sWidth = el.scrollWidth;
            var cWidth = el.clientWidth;
            bodyFixedHeight = bodyFixedHeight - $B.getScrollWidth();
            if(sWidth > cWidth){ /***** 减去滚动条高度 *******/
                this.$bodyWrap.width(sWidth);
            }else{
                this.$bodyWrap.width(cWidth);
            }
            this.$bodyWrap.outerHeight(bodyFixedHeight).css({
                "overflow-y": "auto"
            });
            return bodyFixedHeight;
        },
        _fillParent: function () {
            if (this.opts.fillParent) { //垂直方向沾满父空间
                var fixBum = 0;
                if (this.opts.pgposition === "bottom" || this.opts.pgposition === "both") {
                    fixBum = 40;
                }
                var bodyFixedHeight = this._setBodyWrapHeight(fixBum);
                /*****自动调整页pageSize大小，适配高度*****/
                var size = parseInt( bodyFixedHeight / 38);
                if(size > this.opts.pageSize){/***自动获取下一个pageSize数值****/
                var nextSize;
                    for (var i = 0, len = this.opts.pageList.length; i < len; ++i) {
                        if (this.opts.pageList[i] === this.opts.pageSize) {
                            if(i < len - 2){
                                nextSize = this.opts.pageList[i + 1];
                                break;
                            }else{
                                nextSize =  this.opts.pageList[len - 1];
                            }
                        }
                    }
                    if(nextSize){
                        this.opts.pageSize = nextSize;
                        this.pageSize = nextSize;
                    }
                }
            }
        },
        _setColPosition: function () {
            var startTd = this.hideTrTdArray.first().next();
            if (this.opts.checkBox) {
                startTd = startTd.next();
            }
            var moveXofs = _getMoveXofs(startTd, this);
            this.moveXofs = moveXofs;
        },
        updateColsWidthArray: function () {
            var widthArray = [];
            var keys = Object.keys(this.titleTDs);
            for (var i = 0, len = keys.length; i < len; ++i) {
                widthArray.push(this.titleTDs[keys[i]].outerWidth());
            }
            this.colsWidthArray = widthArray;
            return this.colsWidthArray;
        },
        /**大小变化适配**/
        _onResize: function() {
            var _this = this;
            //检测是否出现了横向滚动条
            var isScroll = false;
            if (this.$table.outerHeight() > this.$bodyWrap.height()) {
                isScroll = true;
            }
            var td, i, len, mWidth;
            //var headTable = this.$headWrap.children("table");
            var headerWidth = this.$headWrap.width();
            if (headerWidth > this.minTableWidth) {
                for (i = 0, len = this.autoTdArray.length; i < len; ++i) {
                    td = this.autoTdArray[i];
                    td.css("width", "100%");
                }
                for (i = 0, len = this.autoTdArray.length; i < len; ++i) {
                    td = this.autoTdArray[i];
                    td.css("width", td.width());
                }
            }else{
                var bodyWidth = this.minTableWidth;
                if(isScroll){
                    bodyWidth = bodyWidth - $B.getScrollWidth();
                }
                this.$bodyWrap.width(bodyWidth);
                for (i = 0, len = this.autoTdArray.length; i < len; ++i) {
                    td = this.autoTdArray[i];
                    mWidth = td.data("minWidth");
                    td.css("width", mWidth);
                }
            }
            this.updateColsWidthArray();
            this._resizeTdSize(isScroll,scrollWidth);
            var el = this.$bodyWrap.parent()[0];
            var sw = el.scrollWidth;
            var cw = el.clientWidth;
            if(sw > cw){
                this.$bodyWrap.width(sw);
            }else{
                this.$bodyWrap.width(cw);
            }
        },
        _resizeTdSize:function(isScroll,scrollWidth){
            var _this = this;
            this.$table.children("tbody").children().each(function () {
                var tdArray = $(this).children();
                var len = tdArray.length;
                if(len === 1){
                    if(tdArray.find("._no_data").length > 0){
                        return true;
                    }
                }
                tdArray.each(function (i) {
                    var w = _this.colsWidthArray[i];
                    if (isScroll && i === len - 1) {
                        w = w - scrollWidth;
                    }
                    var _td = $(this).outerWidth(w);
                    _td.children().outerWidth(w - 2);
                });
            });
            clearTimeout(this._setColPositionTimer);
            this._setColPositionTimer = setTimeout(function () {
                _this._setColPosition();
                _this._hideToolBtnList();
            }, 100);
        },
        getData: function () {
            return this.opts.data;
        },
        /**
         * 打开内嵌页面
         args={
         	content:内容或者url
          	type:如果是url请求的时候，type=html/iframe,
          	onLoaded:fn() 如果是url加载，会触发加载完成事件
         }
         * **/
        openInner: function (tr, args) {
            if (tr.next().hasClass("tr_inner")) {
                return;
            }
            if (this.innerTr) {
                this.innerTr.remove();
            }
            var _this = this;
            var len = tr.children().length;
            var $tr = $("<tr class='tr_inner'><td colspan='" + len + "' style='position:relative;'><div class='tr_inner_content'></div></td></tr>").insertAfter(tr);
            var $td = $tr.children();
            var $content = $td.children();
            $("<a style='position:absolute;top:0;right:0;cursor: pointer;' title='" + $B.config.closeLable + "'><i class='fa fa-cancel-2'></i></a>").appendTo($td).click(function () {
                $tr.remove();
                _this.innerTr = undefined;
            });
            this.innerTr = $tr;
            if (args.type === 'html') {
                $B.htmlLoad({
                    target: $content,
                    url: args.content,
                    loaded: function () {
                        if (typeof args.onLoaded === 'function') {
                            args.onLoaded.call($content);
                        }
                    }
                });
            } else if (args.type === 'iframe') {
                var loading = $("<div style='padding-left:16px;'><i class='fa fa-cog fa-spin fa-1.6x fa-fw margin-bottom'></i>" + $B.config.loading + "</div>").appendTo($content);
                var iframe = $("<iframe  frameborder='0' style='overflow:visible' scrolling='auto' width='100%' height='100%' src='' ></iframe>").appendTo($content.css('overflow', 'hidden'));
                var ifr = iframe[0];
                iframe.on("load", function () {
                    loading.remove();
                    if (typeof args.onLoaded === 'function') {
                        args.onLoaded.call($content);
                    }
                });
                ifr.src = args.content;
            } else {
                $content.html(args.content);
            }
        },
        /**
         * 重新加载
         * args={} 查询参数
         * ****/
        reload: function (args) {
            var _this = this;
            _this.lastParams = {};
            var params = $.extend(true, {
                page: 1,
                pageSize: this.opts.pageSize
            }, args);
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, params);
        },
        /**
         * 采用上一次查询的参数刷新当前页
         * **/
        refresh: function () {
            var _this = this;
            _load.call(_this, function () {
                _makeBody.call(_this);
            }, $.extend({
                page: 1,
                pageSize: this.opts.pageSize
            }, _this.lastParams));
        },
        /*****
         **获取选择的数据
         ********/
        getCheckedData: function (isAll) {
            var res = [];
            this.$table.children("tbody").children().each(function () {
                var $tr = $(this);
                if ($tr.data("isCheck") || isAll) {
                    var d = $.extend(true, {}, $tr.data("data"));
                    delete d.children;
                    delete d.toolbar;
                    res.push(d);
                }
            });
            return res;
        },
        /*****
         **获取选择的数据id集合
         *split 分隔符
         ********/
        getCheckedId: function (split) {
            var res = [];
            var _this = this;
            this.$table.children("tbody").children().each(function () {
                var $tr = $(this);
                if ($tr.data("isCheck")) {
                    var d;
                    if (_this.opts.isTree) {
                        d = $tr.data("data").data[_this.opts.idField];
                    } else {
                        d = $tr.data("data")[_this.opts.idField];
                    }
                    res.push(d);
                }
            });
            return split ? res.join(";") : res;
        },
        getRowCount: function () {
            return this.$table.children("tbody").children().length;
        },
        updateTitle:function(title){
            if(this.$title){
                this.$title.children("h6").html(title);
            }
        }
    };
    $B["Datagrid"] = Datagrid;
    return Datagrid;
}));